using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.VisualStudio.TestTools.LoadTesting;
using System.IO;
using System.Xml;
using Microsoft.Win32;

namespace LoadTestController
{
    public class MyLoadTestPlugin : ILoadTestPlugin
    {
        LoadTest myLoadTest;
        QueryStats m_queryStats;
        WorkflowPostAnalysis m_workflowPostAnalysis;

        const string SalesPerson = "salesperson";
        const string SystemAdministrator = "system administrator";
        const string MarketingProfessional = "marketing professional";
        const string CSR = "customer service representative";
        const string Scheduler = "scheduler";
        const string VPMarketing = "vice president of marketing";
        const string SalesManager = "sales manager";
        const string ScheduleManager = "schedule manager";
        const string CEO = "ceo-business manager";
        const string SupportUser = "support user";
        const string MarketingManager = "marketing manager";
        const string SystemCustomizer = "system customizer";
        const string CSRManager = "csr manager";
        const string VPSales = "vice president of sales";

        public bool ScenarioNameMatchesRoleName(string scenarioName)
        {
            if (scenarioName.ToLower().Contains(SalesPerson) ||
                scenarioName.ToLower().Contains(SystemAdministrator) ||
                scenarioName.ToLower().Contains(MarketingProfessional) ||
                scenarioName.ToLower().Contains(CSR) ||
                scenarioName.ToLower().Contains(Scheduler) ||
                scenarioName.ToLower().Contains(VPMarketing) ||
                scenarioName.ToLower().Contains(SalesManager) ||
                scenarioName.ToLower().Contains(ScheduleManager) ||
                scenarioName.ToLower().Contains(CEO) ||
                scenarioName.ToLower().Contains(SupportUser) ||
                scenarioName.ToLower().Contains(MarketingManager) ||
                scenarioName.ToLower().Contains(SystemCustomizer) ||
                scenarioName.ToLower().Contains(CSRManager) ||
                scenarioName.ToLower().Contains(VPSales))
            {
                return true;
            }
            else
            {
                return false;
            }
        }

        public void Initialize(LoadTest loadTest)
        {
            myLoadTest = loadTest;
            myLoadTest.LoadTestStarting += new EventHandler(ClearSQLCaches);
            myLoadTest.LoadTestFinished += new EventHandler(RunQueryStats);
            myLoadTest.LoadTestStarting += new EventHandler(StartWorkflowTimer);
            myLoadTest.LoadTestFinished += new EventHandler(GetWorkflowStatistics);

            myLoadTest.Heartbeat += new EventHandler<HeartbeatEventArgs>(GetScenarioSettings);
            myLoadTest.TestStarting += new EventHandler<TestStartingEventArgs>(SetRoleForTestFromScenarioName);
        }

        public void ClearSQLCaches(object sender, EventArgs e)
        {
            string prefix = "QueryStats_" + myLoadTest.Name + "_" + DateTime.Now.ToString();
            prefix = prefix.Replace(" ", "_");
            prefix = prefix.Replace("/", "_");
            prefix = prefix.Replace(":", "_");
            m_queryStats = new QueryStats(prefix);

            if (m_queryStats.RunQueryStats == true)
            {
                m_queryStats.FreeProcCache();
            }
        }

        public void RunQueryStats(object sender, EventArgs e)
        {
            if (m_queryStats.RunQueryStats == true)
            {
                m_queryStats.CaptureQueryStats();
            }
        }

        public void StartWorkflowTimer(object sender, EventArgs e)
        {
            m_workflowPostAnalysis = new WorkflowPostAnalysis(myLoadTest.RunSettings.RunDuration, myLoadTest.Name);
        }

        public void GetWorkflowStatistics(object sender, EventArgs e)
        {   
            m_workflowPostAnalysis.Start();
            m_workflowPostAnalysis.RetrieveTables();
            m_workflowPostAnalysis.CreateLog();
        }

        void SetRoleForTestFromScenarioName(object sender, TestStartingEventArgs e)
        {            
            if (ScenarioNameMatchesRoleName(e.ScenarioName))
            {
                if (e.ScenarioName.IndexOf("_") > 0)
                {
                    string roleName = e.ScenarioName.Substring(e.ScenarioName.IndexOf("_") + 1);
                    e.TestContextProperties.Add("UserRole", roleName);
                }
                else
                {
                    e.TestContextProperties.Add("UserRole", e.ScenarioName);
                }
            }
        }        

        void GetScenarioSettings(object sender, EventArgs e)
        {
            try
            {
                string configDirKeyPath = "SOFTWARE\\Microsoft\\MSCRM";
                string configDir = null;

                if (Registry.LocalMachine.OpenSubKey(configDirKeyPath) != null)
                {
                    RegistryKey regKey = Registry.LocalMachine.OpenSubKey(configDirKeyPath);
                    configDir = (string)regKey.GetValue("CRM_Perf_Toolkit_ConfigDir", "c:\\crmstress");
                }
                else
                {
                    //setting the default directory of configsettings.xml to c:\crmstress folder
                    configDir = "c:\\crmstress";
                }

                string filePath = configDir + "\\scenariosettings.xml";
                XmlDocument scenarioSettingsDoc = new XmlDocument();
                scenarioSettingsDoc.Load(filePath);

                XmlNode scenarioSettings = scenarioSettingsDoc.DocumentElement;

                XmlNodeList scenarios = scenarioSettings.SelectNodes("scenario");

                for(int i = 0; i < scenarios.Count; i++)
                {
                    if(true == bool.Parse(scenarios[i].Attributes["dynamic"].Value))
                    {
                        IList<LoadTestScenario> loadtestScenarios = myLoadTest.Scenarios;
                        for(int j = 0; j < loadtestScenarios.Count; j++)
                        {
                            if(loadtestScenarios[j].Name.ToLower().Equals(scenarios[i].Attributes["name"].Value.ToLower()))
                            {
                                int userload = int.Parse(scenarios[i].SelectSingleNode("userload").Attributes["value"].Value);
                                loadtestScenarios[j].CurrentLoad = userload;
                            }
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                System.Diagnostics.Trace.WriteLine(ex.Message);
            }
            
        }
    }
}
